home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1996
/
MacHack 1996.toast
/
Presentations
/
Presentations ’92
/
PatchWorks Kit
/
<PatchWorks++>
/
Patch.h
< prev
next >
Wrap
Text File
|
1992-05-19
|
5KB
|
197 lines
/*
Patch.h
Macros for patching traps and vectors.
by Mouse Herrell & Patrick Beard.
© 1991 Berkeley Systems Inc.
*/
#pragma once
#ifndef __PATCH__
#define __PATCH__
#ifndef __QUICKDRAW__
#include <QuickDraw.h>
#endif
#ifndef __OSUTILS__
#include <OSUtils.h>
#endif
#ifndef __STDDEF__
#include <stddef.h>
#endif
// Macros & Inline glue to make patching easier.
#define GetTrapType(x) (((x) & 0x800) != 0)
#define InterruptMask(x) ((x) << 8)
#define cSupervisorState 0x2000
#pragma parameter __D0 GetA4
void* GetA4(void) = { 0x200c };
#pragma parameter __D0 SetA4(__D0)
void* SetA4(void* newA4) = { 0xc18c };
#pragma parameter __D0 GetA5
void* GetA5(void) = { 0x200d };
#pragma parameter __D0 GetA0
void* GetA0(void) = { 0x2008 };
#pragma parameter __D0 GetSR
short GetSR(void) = { 0x40c0 };
#pragma parameter __D0 SetSR(__D1)
short SetSR(short) = { 0x40c0, 0x46c1 };
// tests and sets indivisibly (to avoid race conditions) using BSET.B #0
#pragma parameter __D0 SetFlag(__A0)
Boolean SetFlag(Boolean*) = { 0x08d0, 0x0000, 0x56c0 };
// types & constants.
enum PatchError {
eAbstractErr = 128, // An abstract method was called.
eBuriedPatchErr, // The patch removal failed because the vector has changed.
eEndPatchErrors
};
typedef enum PatchError PatchError;
enum {
ePatchOff = 0,
ePatchOn
};
typedef char PatchState;
// universal pointer to function.
typedef void* PatchProcPtr;
typedef PatchProcPtr *PatchVectorPtr; // pointer to a PatchProcPtr.
// stub of code that is allocated for every patch.
class Patch;
struct PatchStub {
short itsJsrJmp;
PatchProcPtr itsAgent;
Patch* itsPatch;
};
typedef struct PatchStub PatchStub;
// patch class.
class Patch {
protected:
Patch(); // constructor protected to prevent direct use.
public:
virtual ~Patch(); // destruction is allowed.
void Install(void); // install the patch. delete to remove.
static void RemoveAll(void); // remove all installed patches.
void Enable(void); // enable the patch.
void Disable(void); // disable the patch.
PatchState Switch(PatchState state); // get & set state.
void* operator new(size_t n); // memory allocator.
void operator delete(void* p); // memory deallocator.
protected:
virtual PatchProcPtr GetAgent(void); // returns pointer to agent code.
virtual PatchProcPtr Get(void); // retrieve the old address.
virtual void Set(PatchProcPtr proc); // set the new address.
protected:
#ifndef THINK_C
short itsClassId; // padding for universal glue.
#endif
static Patch* theirList; // list of all installed patches.
Patch* itsNext; // next patch after this one.
PatchProcPtr itsBehavior; // routine to call when patch hit.
PatchProcPtr itsOld; // old routine to call.
PatchStub* itsStub; // the universal glue code.
void* itsGlobals; // pointer to globals.
Boolean itsInstalled; // if patch was ever installed.
PatchState itsState; // state of patch (enabled/disabled).
};
class TrapPatch : public Patch {
public:
void InitTrapPatch(PatchProcPtr proc, short trap);
protected:
virtual PatchProcPtr Get(void);
virtual void Set(PatchProcPtr proc);
protected:
short itsTrap;
};
class VectorPatch : public Patch {
public:
void InitVectorPatch(PatchProcPtr proc, PatchVectorPtr vector);
protected:
virtual PatchProcPtr Get(void);
virtual void Set(PatchProcPtr proc);
private:
PatchVectorPtr itsVector;
};
// structure that represents the stack frame when the patch is given control.
struct PatchFrame {
Patch* patch; // pointer to current patch object.
void* offset; // magic address to adjust stack for tail patching.
long rd0; // caller's d0-d2/a0-a1 which might contain
long rd1; // parameters which patch can change.
long rd2;
void* ra0;
void* ra1;
void* ra4; // caller's a4 & a5 in case we use a4 globals.
void* ra5;
void* link; // link to previous stack frame. 28(sp)
void* old; // old address that will be returned to.
void* caller; // caller's address. 36(sp)
char parameters[1]; // array of parameters (if any)
};
typedef struct PatchFrame PatchFrame;
struct ExceptionPatchFrame {
Patch* patch; // pointer to current patch object.
void* offset; // magic address to adjust stack for tail patching.
long rd0; // caller's d0-d2/a0-a1 which might contain
long rd1; // parameters which patch can change.
long rd2;
void* ra0;
void* ra1;
void* ra4; // caller's a4 & a5 in case we use a4 globals.
void* ra5;
void* link; // link to previous stack frame.
void* old; // old address that will be returned to.
short status; // value of status register.
void* caller; // callers's address.
char parameters[1]; // array of parameters (if any)
};
typedef struct ExceptionPatchFrame ExceptionPatchFrame;
void CallOS(PatchFrame* frame);
void VException(ExceptionPatchFrame frame);
void PatchExceptions(void);
void RestoreExceptions(void);
#endif